use crate::TextCommands;
use indicatif::{ProgressBar, ProgressStyle};
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;

#[derive(Debug, Serialize, Deserialize)]
pub struct TextStats {
    pub lines: usize,
    pub words: usize,
    pub characters: usize,
    pub bytes: usize,
    pub paragraphs: usize,
    pub sentences: usize,
    pub code_lines: usize,
    pub comment_lines: usize,
    pub blank_lines: usize,
}

impl TextStats {
    pub fn new() -> Self {
        Self {
            lines: 0,
            words: 0,
            characters: 0,
            bytes: 0,
            paragraphs: 0,
            sentences: 0,
            code_lines: 0,
            comment_lines: 0,
            blank_lines: 0,
        }
    }
    
    pub fn analyze_text(&mut self, text: &str) {
        self.bytes = text.len();
        self.characters = text.chars().count();
        self.lines = text.lines().count();
        self.words = text.split_whitespace().count();
        self.paragraphs = text.split("\n\n").count();
        self.sentences = text.split(&['.', '!', '?'][..]).count() - 1;
        
        // 分析代码行
        for line in text.lines() {
            let trimmed = line.trim();
            if trimmed.is_empty() {
                self.blank_lines += 1;
            } else if trimmed.starts_with("//") || trimmed.starts_with("#") || trimmed.starts_with("/*") {
                self.comment_lines += 1;
            } else {
                self.code_lines += 1;
            }
        }
    }
}

pub fn handle_text_commands(command: TextCommands, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    match command {
        TextCommands::Count { file, type_ } => {
            let stats = text_count(&file, verbose)?;
            print_text_stats(&stats, &type_);
        },
        TextCommands::Replace { pattern, replacement, file, output, regex, global } => {
            text_replace(&pattern, &replacement, &file, output.as_deref(), regex, global, verbose)?;
        },
        TextCommands::Format { file, format, output } => {
            text_format(&file, &format, output.as_deref(), verbose)?;
        },
        TextCommands::Sort { file, field, numeric, reverse } => {
            text_sort(&file, field, numeric, reverse, verbose)?;
        },
        TextCommands::Unique { file, output, ignore_case } => {
            text_unique(&file, output.as_deref(), ignore_case, verbose)?;
        },
    }
    Ok(())
}

fn text_count(file: &Path, verbose: bool) -> Result<TextStats, Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("分析文本...");
    
    let contents = fs::read_to_string(file)?;
    let mut stats = TextStats::new();
    stats.analyze_text(&contents);
    
    pb.finish_with_message("✅ 分析完成");
    Ok(stats)
}

fn text_replace(
    pattern: &str, 
    replacement: &str, 
    file: &Path, 
    output: Option<&Path>,
    use_regex: bool,
    global: bool,
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("处理文本替换...");
    
    let contents = fs::read_to_string(file)?;
    let new_contents = if use_regex {
        let regex = Regex::new(pattern)?;
        if global {
            regex.replace_all(&contents, replacement).to_string()
        } else {
            regex.replace(&contents, replacement).to_string()
        }
    } else {
        if global {
            contents.replace(pattern, replacement)
        } else {
            if let Some(pos) = contents.find(pattern) {
                let mut result = contents;
                result.replace_range(pos..pos + pattern.len(), replacement);
                result
            } else {
                contents
            }
        }
    };
    
    match output {
        Some(path) => {
            fs::write(path, &new_contents)?;
            if verbose {
                println!("替换完成，已保存到: {}", path.display());
            }
        },
        None => {
            print!("{}", new_contents);
        },
    }
    
    pb.finish_with_message("✅ 替换完成");
    Ok(())
}

fn text_format(file: &Path, format: &str, output: Option<&Path>, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("格式化文本...");
    
    let contents = fs::read_to_string(file)?;
    let formatted = match format {
        "json" => {
            let json_value: serde_json::Value = serde_json::from_str(&contents)?;
            serde_json::to_string_pretty(&json_value)?
        },
        "xml" => {
            let mut reader = quick_xml::Reader::from_str(&contents);
            let mut writer = quick_xml::Writer::new(Vec::new());
            writer.write_event(quick_xml::events::Event::Text(quick_xml::events::BytesText::new(&contents)))?;
            String::from_utf8(writer.into_inner())?
        },
        "yaml" => {
            let yaml_value: serde_yaml::Value = serde_yaml::from_str(&contents)?;
            serde_yaml::to_string(&yaml_value)?
        },
        "markdown" => {
            // 简单的 Markdown 格式化
            format_markdown(&contents)
        },
        _ => return Err("不支持的格式化类型".into()),
    };
    
    match output {
        Some(path) => {
            fs::write(path, &formatted)?;
            if verbose {
                println!("格式化完成，已保存到: {}", path.display());
            }
        },
        None => {
            print!("{}", formatted);
        },
    }
    
    pb.finish_with_message("✅ 格式化完成");
    Ok(())
}

fn text_sort(file: &Path, field: Option<usize>, numeric: bool, reverse: bool, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("排序文本...");
    
    let contents = fs::read_to_string(file)?;
    let mut lines: Vec<&str> = contents.lines().collect();
    
    lines.sort_by(|a, b| {
        let a_val = if let Some(field_idx) = field {
            a.split_whitespace().nth(field_idx).unwrap_or("")
        } else {
            a
        };
        
        let b_val = if let Some(field_idx) = field {
            b.split_whitespace().nth(field_idx).unwrap_or("")
        } else {
            b
        };
        
        let comparison = if numeric {
            a_val.parse::<f64>().unwrap_or(0.0).partial_cmp(&b_val.parse::<f64>().unwrap_or(0.0)).unwrap()
        } else {
            a_val.cmp(b_val)
        };
        
        if reverse {
            comparison.reverse()
        } else {
            comparison
        }
    });
    
    let sorted = lines.join("\n");
    print!("{}", sorted);
    
    if verbose {
        println!("\n✅ 排序完成，共处理 {} 行", lines.len());
    }
    
    pb.finish_with_message("✅ 排序完成");
    Ok(())
}

fn text_unique(file: &Path, output: Option<&Path>, ignore_case: bool, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("去重文本...");
    
    let contents = fs::read_to_string(file)?;
    let lines: Vec<&str> = contents.lines().collect();
    
    let mut unique_lines = Vec::new();
    let mut seen = std::collections::HashSet::new();
    
    for line in lines {
        let key = if ignore_case {
            line.to_lowercase()
        } else {
            line.to_string()
        };
        
        if seen.insert(key) {
            unique_lines.push(line);
        }
    }
    
    let result = unique_lines.join("\n");
    
    match output {
        Some(path) => {
            fs::write(path, &result)?;
            if verbose {
                println!("去重完成，已保存到: {}", path.display());
            }
        },
        None => {
            print!("{}", result);
        },
    }
    
    if verbose {
        println!("\n✅ 去重完成，原始 {} 行，去重后 {} 行", lines.len(), unique_lines.len());
    }
    
    pb.finish_with_message("✅ 去重完成");
    Ok(())
}

fn format_markdown(text: &str) -> String {
    let mut formatted = String::new();
    let mut in_code_block = false;
    let mut code_block_lang = String::new();
    
    for line in text.lines() {
        let trimmed = line.trim();
        
        if trimmed.starts_with("```") {
            in_code_block = !in_code_block;
            if in_code_block {
                code_block_lang = trimmed[3..].to_string();
            }
            formatted.push_str(line);
            formatted.push('\n');
        } else if in_code_block {
            // 在代码块中，保持原样
            formatted.push_str(line);
            formatted.push('\n');
        } else {
            // 格式化 Markdown
            let formatted_line = format_markdown_line(line);
            formatted.push_str(&formatted_line);
            formatted.push('\n');
        }
    }
    
    formatted
}

fn format_markdown_line(line: &str) -> String {
    let mut formatted = line.to_string();
    
    // 格式化标题
    if line.starts_with("#") {
        let level = line.chars().take_while(|&c| c == '#').count();
        let content = line[level..].trim();
        formatted = format!("{} {}", "#".repeat(level), content);
    }
    
    // 格式化列表
    if line.starts_with("- ") || line.starts_with("* ") {
        formatted = format!("• {}", line[2..].trim());
    }
    
    // 格式化代码
    if line.contains("`") {
        let re = Regex::new(r"`([^`]+)`").unwrap();
        formatted = re.replace_all(&formatted, "`$1`").to_string();
    }
    
    formatted
}

fn print_text_stats(stats: &TextStats, type_: &str) {
    match type_ {
        "lines" => println!("行数: {}", stats.lines),
        "words" => println!("单词数: {}", stats.words),
        "chars" => println!("字符数: {}", stats.characters),
        "bytes" => println!("字节数: {}", stats.bytes),
        "paragraphs" => println!("段落数: {}", stats.paragraphs),
        "sentences" => println!("句子数: {}", stats.sentences),
        "code" => println!("代码行数: {}", stats.code_lines),
        "comments" => println!("注释行数: {}", stats.comment_lines),
        "blank" => println!("空行数: {}", stats.blank_lines),
        "all" => {
            println!("📊 文本统计:");
            println!("  行数: {}", stats.lines);
            println!("  单词数: {}", stats.words);
            println!("  字符数: {}", stats.characters);
            println!("  字节数: {}", stats.bytes);
            println!("  段落数: {}", stats.paragraphs);
            println!("  句子数: {}", stats.sentences);
            println!("  代码行数: {}", stats.code_lines);
            println!("  注释行数: {}", stats.comment_lines);
            println!("  空行数: {}", stats.blank_lines);
        },
        _ => println!("不支持的统计类型"),
    }
}


